//ImageMGR.cpp
#include "ImageMGR.h"
#include "Array.h"

#include <mysql++.h>

#include <iostream>
#include <string>
#include <memory.h>
#include <cstdlib>
#include <cstdio>
#include <fstream>
#include <fcntl.h>
#include <unistd.h>

using namespace mysqlpp;

//////////////////////////////////////////////////////////////////
//	Constructor & Destructor									//
//////////////////////////////////////////////////////////////////

//Constructor
ImageMGR::ImageMGR()
{
}


//Destructor
ImageMGR::~ImageMGR()
{
}

//////////////////////////////////////////////////////////////////
//	MemberFunction												//
//////////////////////////////////////////////////////////////////

//DescriptionAnalyzer
string& ImageMGR::DescriptionAnalyzer( string description )
{
	int startPosition = 0;
	int endPosition = 0;

	cout << endl << ">> Searching Image File..." << endl << endl;

	string temp = description;
	
	//Find "img"
	int flag1 = description.find( string( "img" ) );

	//Find "IMG"
	int flag2 = description.find( string( "IMG" ) );

	//Finde"image"
	int flag3 = -1;

	if( flag1 == -1 && flag2 == -1 )
	{
		flag3 = description.find( string( "image" ) );	//egloos
	}

	if( ( flag1 != -1 ) || ( flag2 != -1 ) || ( flag3 != -1 ) )
	{
		int select = 0;
		
		if( flag1 == -1 )
		{
			flag1 = 65536;
		}
		
		if( flag2 == -1 )
		{
			flag2 = 65536;
		}
		
		if( flag3 == -1 )
		{
			flag3 = 65536;
		}

		if( flag1 < flag2 && flag1 < flag3 )
		{
			select = flag1;
		}
		else if( flag2 < flag1 && flag2 < flag3 )
		{
			select = flag2;
		}
		else if( flag3 < flag1 && flag3 < flag2 )
		{
			select = flag3;
		}
		
		if( flag1 == select && flag1 != -1 )
		{
			//Get Start Position
			startPosition = description.find( string( "http" ), flag1 );

			//Get End Position
			endPosition = description.find( string("\""), startPosition );

			if( endPosition == -1 )
			{
				endPosition = description.find( string("&"), startPosition );
			}
		}
		else if( flag2 == select && flag2 != -1 )
		{
			//Get Start Position
			startPosition = description.find( string( "http" ), flag2 );
			
			//Get End Position
			endPosition = description.find( string("\""), startPosition );

			if( endPosition == -1 )
			{
				endPosition = description.find( string("&"), startPosition );
			}
		}
		else if( flag3 == select && flag3 != -1 )	//egloos
		{
			//Get Start Position
			startPosition = description.find( string( "http" ), flag3 );
			
			//Get End Position
			endPosition = description.find( string("\""), startPosition );

			if( endPosition == -1 )
			{
				endPosition = description.find( string("&"), startPosition );
			}
		}

		int lastPosition = description.length();
		try{
			//Erase Head Part
	    	 description.erase( 0, startPosition );
		
			//Caculate Position
			endPosition = endPosition - startPosition;

			description.erase( endPosition, lastPosition );
		}
		catch( const std::out_of_range& er )
		{
			description = temp;
		}
	}

	if( temp == description )
	{
		int length = description.length();
		
		description.erase( 0, length );
	}

	return description;
}



//ImageDownloader [ return : filename ]
string& ImageMGR::ImageDownloader( string imageLink )
{
	//Get Length of imageLink string
	int length = imageLink.length();

	//Declaration char type array at heep space ( 5 -> "wget " )
	char* command = new char[ 1024 ];

	//Set System Command for Download the imageFile
	sprintf( command, "wget %s", const_cast<char*>( imageLink.c_str() ) );

	//Run Command
	int flag = system( command );

	if( flag == 0 )
	{
		//Declaration Variable
		int searchPosition = 0;

		//Loop for find filename
		while( searchPosition != -1 )
		{
			searchPosition = imageLink.find( string("/") );

			if( searchPosition > 0 )
			{
				imageLink.erase( 0, searchPosition );
			}
			else if( searchPosition == 0 )
			{
				imageLink.erase( 0 ,1 );
			}
		}//while end

		cout << endl << ">> Image Download Success..." << endl;
	}
	else
	{
		int length = imageLink.length();

		imageLink.erase( 0, length );
	}

	//delete command
	delete[] command;

	//return
	return imageLink;	
}


//ThumbnailMaker
string ImageMGR::ThumbnailMaker( string filename, string itemLink )
{
	//Get Length of filname
	int length = filename.length();
	
	//Declaration char* type variable
	char* command;

	//Declaration filetype variable
	string filetype = filename;
	
	//Declaration thumbnail variable
	string thumbnail = itemLink;
	//<---------Make the file name---------->
	int position = 0;

	//Get filetype( ex. jpg, gif ... )
	position = filetype.find( string( "." ) );

	if( position != -1 )
	{
		filetype.erase( 0, position );
	}

	int filetypeLength = filetype.length();

	if( filetypeLength > 5 || filetypeLength < 1 )
	{
		filetype = ".jpg";
	}

	//Get filename
	position = 0;
	
	thumbnail.erase( 0, 7 );

	//change '/' to '-'
	while( position != -1 )
	{
		position = thumbnail.find( string( "/" ) );
		
		if( position != -1 )
		{
			if( ( position != 0 ) )
			{
				thumbnail[ position ] = '-';
			}
		}
	}

	position = 0;

	//change '.' to '-'
	while( position != -1 )
	{
		position = thumbnail.find( string( "." ) );
		
		if( position != -1 )
		{
			if( ( position != 0 ) )
			{
				thumbnail[ position ] = '-';
			}
		}
	}

	char* thumbfilename = new char[ 1024 ];

	sprintf( thumbfilename, "%s%s", const_cast<char*>( thumbnail.c_str() ), const_cast<char*>( filetype.c_str() ) );

	//Create variable in heep space
	command = new char[ 1024 ];

	//Set Command
	cout << ">> Creating Thumbnail File..." << endl << endl;
	
	sprintf( command, "convert %s -thumbnail x200 -resize '200x<' -resize 50%% -gravity NorthWest -crop 80x90+0+0  +repage %s",
			 const_cast<char*>( filename.c_str() ), thumbfilename ); 

	string returnValue = thumbfilename;

	//Run Command
	system( command );

	delete[] command;

	sleep(1);
	
	//Remove source image

	//Create variable in heep space
	command = new char[ 1024 ];

	sprintf( command, "rm %s", const_cast<char*>( filename.c_str() ) );

	system( command );
	
	//Delete variable in heep space
	delete[] thumbfilename;
	delete[] command;

	return returnValue;
}



//ImageDeliver
void ImageMGR::ImageDeliver( string filename, string itemLink )
{
	//Declaration char* type variable
	char* command;

	
	//<------Get New File Name----->
	string buffer = filename;

	int length = buffer.length();

	int position = buffer.find( string( "." ) );

	buffer.erase( position, length - 1 );

	//<-----Convert to png file----->
	cout << ">> Converting to PNG file..." << endl;
	
	command = new char[ 1024 ];

	sprintf( command, "convert %s %s.png", const_cast<char*>( filename.c_str() ), const_cast<char*>( buffer.c_str() ) );

	//cout << endl << endl << ">> " << command << endl << endl;
	
	system( command );

	delete[] command;


	//Set Rigth
	cout << endl << "Right Setting..." << endl << endl;

	command = new char[ 1024 ];

	sprintf( command, "chmod 777 %s %s.png", const_cast<char*>( filename.c_str() ), const_cast<char*>( buffer.c_str() ) );

	system( command );

	delete[] command;

	//<-----Create Target Directory----->
	cout << ">> Creating Directories and Copying Files..." << endl;
	
	string directory = buffer;

	int directoryLength = directory.length();

	//Create Local Directory
	command = new char[ 1024 ];
	
	sprintf( command, "mkdir ./ThumbnailImages/%s", const_cast<char*>( directory.c_str() ) );

	system( command );

	delete[] command;
	
	//Copy PNG file to local directory
	command = new char[ 1024 ];

	sprintf( command, "cp %s.png ./ThumbnailImages/%s",  const_cast<char*>( directory.c_str() ), const_cast<char*>( directory.c_str() ) );

	system( command );

	delete[] command;
	
	//Create JSP Directory
	command = new char[ 1024 ];

	sprintf( command, "mkdir /usr/local/tomcat/jakarta-tomcat-5.0.19/webapps/jsp-examples/ThumbnailImages/%s", const_cast<char*>( directory.c_str() ) );


	system( command );

	delete[] command;

	//Move Image file to JSP Directory
	command = new char[ 1024 ];

	sprintf( command, "cp %s /usr/local/tomcat/jakarta-tomcat-5.0.19/webapps/jsp-examples/ThumbnailImages/%s",
			 const_cast<char*>( filename.c_str() ), const_cast<char*>( directory.c_str() ) );

	system( command );

	delete[] command;

	//Remove the imageFile
	cout << ">> Removing Temp Files..." << endl;
	
	command = new char[ 1024 ];

	sprintf( command, "rm %s %s.png", const_cast<char*>( filename.c_str() ),  const_cast<char*>( buffer.c_str() ) );

	system( command );

	delete[] command;

	sleep(1);


	//<------------------Record the database----------------->
	
	//Open the database
	Connection con( "rss", "localhost", "root", "dreams" );

	//Declaration Query Variable
	Query query = con.query();

	//이전 쿼리
	/*
	//Set Query Statement
	query << "call InsertThumbnailImage( \""
		  << const_cast<char*>( filename.c_str() ) << "\", \""
		  << const_cast<char*>( buffer.c_str() ) << ".png\", \""
		  << const_cast<char*>( itemLink.c_str() ) << "\", \"//192.168.1.10/jsp-examples/ThumbnailImages/"
		  << const_cast<char*>( directory.c_str() ) << "/"
		  << const_cast<char*>( filename.c_str() ) << "\", \"/ThumbnailImages/" 
		  << const_cast<char*>( directory.c_str() )<< "\" );";

	//예제
	//call InsertThumbnailImage(
	//"lanil-tistory-com-37.jpg",
	//"lanil-tistory-com-37.png",
	//"http://lanil.tistory.com/37",
	//"//192.168.1.10/jsp-examples/ThumbnailImages/lanil-tistory-com-37/lanil-tistory-com-37.jpg",
	//"/ThumbnailImages/lanil-tistory-com-37" );
	*/

	//변경된 쿼리 
	query << "insert into ThumbnailImage values ( \""
		<< const_cast<char*>( filename.c_str() ) << "\", \""
		<< const_cast<char*>( buffer.c_str() ) << ".png\", \""
		<< const_cast<char*>( itemLink.c_str() ) << "\", \"//192.168.1.10/jsp-examples/ThumbnailImages/"
		<< const_cast<char*>( directory.c_str() ) << "/"
		<< const_cast<char*>( filename.c_str() ) << "\", \"/ThumbnailImages/"
		<< const_cast<char*>( directory.c_str() )<< "\" );";

	
	try{
		string preview = query.preview();

		cout << endl << ">> Query Preview : " << preview << endl;

		query.execute();
	}
	catch( const BadQuery& er )
	{
		cerr << ">> Query Error : " << er.what() << endl;

		sleep(1);
	}
}



//MakeThumbnail
void ImageMGR::MakeThumbnail( string description, string itemLink )
{
	//Open the database
	Connection con( "rss", "localhost", "root", "dreams" );

	//Declaration Query Variable
	Query query = con.query();

	//Set Query Statement
	query << "select * from ThumbnailImage where itemLink=\""
		  << const_cast<char*>( itemLink.c_str() ) << "\"";

	Result res = query.store();

	sleep(1);

	int flag = 0;
	
	flag = res.num_rows();

	if( flag == 0 )
	{
		//Call DescriptionAnalyzer
		string imageLink = this->DescriptionAnalyzer( description );

		if( !imageLink.empty() )
		{
			cout << ">> Find Image Link : " << imageLink << endl << endl;
	
			sleep(1);

			//Call ImageDownloader
			string filename = this->ImageDownloader( imageLink );

			if( !filename.empty() )
			{
				cout << ">> Filename : " << filename << endl << endl;

				sleep(1);

				//Call ThmbnailMaker
				filename = this->ThumbnailMaker( filename, itemLink );

				//ImageDeliver
				this->ImageDeliver( filename, itemLink );
			}
			else
			{
				cout << endl << ">> Image Download Fail...."<< endl;

				sleep(1);
			}
		}
		else
		{
			cout << endl << ">> Don't find image..." << endl << endl;

			sleep(1);
		}
	}
	else
	{
		cout << "Image is already exist!" << endl << endl;
	}
}



//Test Main
#if 0

int main()
{
	ImageMGR imageMGR;

	string input = ">&nbsp; &nbsp; <img src=\"http://imgnews.naver.com/image/111/2007/02/10/1171051345_1.jpg\" border=\"0\" width=\"500\"> <br /> &lt;조이뉴스24&gt;<p>\"이동국은 곧 기회를 잡을 것이다. 그는 출전이 가능할 정도로 서서히 팀과 프리미어리그에 적응해 가고 있다.\"</p><p>가레스 사우스게이트 미들즈브러 감독이 <a style=\"\" onclick=\"keyword_popup(event, '5778')\" onmouseover=\"style.color='#FF0000';style.cursor='hand';\" ";
	
	string itemLink = "http://uccviewer.tistory.com/138";
	
	imageMGR.MakeThumbnail( input, itemLink );
	
	return 0;
}
#endif


